<?php

/* 访问控制 */
if (! defined('IN_ECTOUCH')) {
    die('Deny Access');
}

$payment_lang = ROOT_PATH . 'languages/' .$GLOBALS['_CFG']['lang']. '/payment/wxpay.php';

if (file_exists($payment_lang)) {
    include_once ($payment_lang);
    L($_LANG);
}

/* 模块的基本信息 */
if (isset($set_modules) && $set_modules == TRUE) {
    $i = isset($modules) ? count($modules) : 0;
    /* 代码 */
    $modules[$i]['code'] = basename(__FILE__, '.php');
    /* 描述对应的语言项 */
    $modules[$i]['desc'] = 'wxpay_desc';
    /* 是否支持货到付款 */
    $modules[$i]['is_cod'] = '0';
    /* 是否支持在线支付 */
    $modules[$i]['is_online'] = '1';
    /* 作者 */
    $modules[$i]['author'] = 'RG808 TEAM';
    /* 网址 */
    $modules[$i]['website'] = 'http://www.rg808.com/';
    /* 版本号 */
    $modules[$i]['version'] = '0.02';
    /* 配置信息 */

    /* 配置信息 */
    $modules[$i]['config']  = array(
        array('name' => 'wxpay_appid',			'type' => 'text',   'value' => ''),
        array('name' => 'wxpay_appsecret',		'type' => 'text',   'value' => ''),
        array('name' => 'wxpay_mchid',			'type' => 'text',   'value' => ''),
        array('name' => 'wxpay_key',			'type' => 'text',	'value' => ''),
        array('name' => 'wxpay_signtype',		'type' => 'text',	'value' => 'sha1')
    );
    
    return;
}

/**
 * 微信支付类
 */
class wxpay
{

    var $parameters; // cft 参数
    var $payment; // 配置信息
    /**
     * 生成支付代码
     *
     * @param array $order
     *            订单信息
     * @param array $payment
     *            支付方式信息
     */
    function get_code($order, $payment)
    {
        if (!defined('EC_CHARSET')){
            $charset = 'utf-8';
        }else{
            $charset = EC_CHARSET;
        }

		$wx_openid = cookie('wx_openid');

        $ua = strtolower($_SERVER['HTTP_USER_AGENT']);
        if( !preg_match('/micromessenger/', $ua)){
            return '<div style="text-align:center"><button class="btn btn-primary" type="button" disabled>请在微信中支付</button></div>';
        }
        if(!isset($wx_openid) || empty($wx_openid)){
            return '<div style="text-align:center"><button class="btn btn-primary" type="button" disabled>未得权限</button></div>';
        }

        $charset = strtoupper($charset);
        // 配置参数
        $this->payment = $payment;

        $this->setParameter("openid",			$wx_openid); // 商品描述
        $this->setParameter("body",				$order['order_sn']); // 商品描述
        $this->setParameter("out_trade_no",		$order['order_sn'] . 'O' . $order['log_id']); // 商户订单号
        $this->setParameter("total_fee",		$order['order_amount'] * 100); // 总金额
        $this->setParameter("notify_url",		__URL__ . '/notify_url.php'); // 通知地址
        $this->setParameter("trade_type",		"JSAPI"); // 交易类型
        $this->setParameter("input_charset",	$charset);

        $prepay_id = $this->getPrepayId();
        $jsApiParameters = $this->getParameters($prepay_id);

        $js = '<script language="javascript">
        function jsApiCall(){WeixinJSBridge.invoke("getBrandWCPayRequest",' . $jsApiParameters . ',function(res){if(res.err_msg == "get_brand_wcpay_request:ok"){location.href="' . return_url(basename(__FILE__, '.php'), array(
            'status' => 2
        )) . '"}else{location.href="' . return_url(basename(__FILE__, '.php'), array(
            'status' => 0
        )) . '"}});}function callpay(){if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){document.addEventListener("WeixinJSBridgeReady", jsApiCall, false);}else if (document.attachEvent){document.attachEvent("WeixinJSBridgeReady", jsApiCall);document.attachEvent("onWeixinJSBridgeReady", jsApiCall);}}else{jsApiCall();}}
            </script>';
        
        $button = '<div style="text-align:center"><button class="btn btn-primary" type="button" onclick="callpay()">微信安全支付</button></div>' . $js;
        
        return $button;
    }

	/**
     * 响应操作
     */
    function callback($data){
		$postdata = json_decode(json_encode(simplexml_load_string($GLOBALS['HTTP_RAW_POST_DATA'], 'SimpleXMLElement', LIBXML_NOCDATA)), true);
		$this->payment = model('Payment')->get_payment($data['code']);
		
		// 微信端签名
		$wxsign = $postdata['sign'];
		unset($postdata['sign']);
		
		$sign	= $this->getSign($postdata);
		
$file	= fopen(ROOT_PATH."/Log/Log_".date("Ymd").".txt", "a+");
fwrite($file, "\n\n-------".date('H:i:s')."---------\n");
fwrite($file, $wxsign .'=='. $sign."\n");
fwrite($file, var_export($postdata, true));
fclose($file);
		
		if ( $wxsign == $sign ) {
			if ($postdata["return_code"] == "SUCCESS") {
				$out_trade_no = explode('O', $postdata['out_trade_no']);
				$log_id = $out_trade_no[1]; // 订单号log_id
				model('Payment')->order_paid($log_id, 2); // 改变订单状态
				
				if ( $data['status'] == 1 ){
					echo "success";exit;
				}else{
					return true;
				}
			}
		}
		if ( $data['status'] == 1 ){
			echo "fail";exit;
		}else if ( $data['status'] == 2 ){
			return true; 
		}else{
			return false;
		}
    }

    /**
     * 响应操作
     */
    function notify($data)
    {
        $this->callback($data);
    }

    function trimString($value)
    {
        $ret = null;
        if (null != $value) {
            $ret = $value;
            if (strlen($ret) == 0) {
                $ret = null;
            }
        }
        return $ret;
    }

    /**
     * 作用：产生随机字符串，不长于32位
     */
    public function createNoncestr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i ++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    /**
     * 作用：设置请求参数
     */
    function setParameter($parameter, $parameterValue)
    {
        $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
    }

    /**
     * 作用：生成签名
     */
    public function getSign($Obj)
    {
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        // 签名步骤一：按字典序排序参数
        ksort($Parameters);
        
        $buff = "";
        foreach ($Parameters as $k => $v) {
            $buff .= $k . "=" . $v . "&";
        }
        $String="";
        if (strlen($buff) > 0) {
            $String = substr($buff, 0, strlen($buff) - 1);
        }
        // echo '【string1】'.$String.'</br>';
        // 签名步骤二：在string后加入KEY
        $String = $String . "&key=" . $this->payment['wxpay_key'];
        // echo "【string2】".$String."</br>";
        // 签名步骤三：MD5加密
        $String = md5($String);
        // echo "【string3】 ".$String."</br>";
        // 签名步骤四：所有字符转为大写
        $result_ = strtoupper($String);
        // echo "【result】 ".$result_."</br>";
        return $result_;
    }

    /**
     * 获取prepay_id
     */
    function getPrepayId()
    {
        // 设置接口链接
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        try {
            // 检测必填参数
            if ($this->parameters["out_trade_no"] == null) {
                throw new Exception("缺少统一支付接口必填参数out_trade_no！" . "<br>");
            } elseif ($this->parameters["body"] == null) {
                throw new Exception("缺少统一支付接口必填参数body！" . "<br>");
            } elseif ($this->parameters["total_fee"] == null) {
                throw new Exception("缺少统一支付接口必填参数total_fee！" . "<br>");
            } elseif ($this->parameters["notify_url"] == null) {
                throw new Exception("缺少统一支付接口必填参数notify_url！" . "<br>");
            } elseif ($this->parameters["trade_type"] == null) {
                throw new Exception("缺少统一支付接口必填参数trade_type！" . "<br>");
            } elseif ($this->parameters["trade_type"] == "JSAPI" && $this->parameters["openid"] == NULL) {
                throw new Exception("统一支付接口中，缺少必填参数openid！trade_type为JSAPI时，openid为必填参数！" . "<br>");
            }
            $this->parameters["appid"]				= $this->payment['wxpay_appid']; // 公众账号ID
            $this->parameters["mch_id"]				= $this->payment['wxpay_mchid']; // 商户号
            $this->parameters["spbill_create_ip"]	= $_SERVER['REMOTE_ADDR']; // 终端ip
            $this->parameters["nonce_str"]			= $this->createNoncestr(); // 随机字符串
            $this->parameters["sign"]				= $this->getSign($this->parameters); // 签名

            $xml = "<xml>";
            foreach ($this->parameters as $key => $val) {
                if (is_numeric($val)) {
                    $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
                } else {
                    $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
                }
            }
            $xml .= "</xml>";
        } catch (Exception $e) {
            die($e->getMessage());
        }

        $response = Http::curlPost($url, $xml, 30);
        $result = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        $prepay_id = $result["prepay_id"];
        return $prepay_id;
    }

    /**
     * 作用：设置jsapi的参数
     */
    public function getParameters($prepay_id)
    {
        $jsApiObj["appId"] = $this->payment['wxpay_appid'];
        $timeStamp = time();
        $jsApiObj["timeStamp"] = "$timeStamp";
        $jsApiObj["nonceStr"] = $this->createNoncestr();
        $jsApiObj["package"] = "prepay_id=$prepay_id";
        $jsApiObj["signType"] = "MD5";
        $jsApiObj["paySign"] = $this->getSign($jsApiObj);
        $this->parameters = json_encode($jsApiObj);
        
        return $this->parameters;
    }

}